﻿using LitJson;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using WxSDK.Common;
using WxSDK.Config;

namespace WxSDK.WxMini
{
	/// <summary>
	/// 微信小程序API
	/// </summary>
	public class WxMiniApi
	{
		/// <summary>
		/// 登录凭证校验。返回json：{"openid":"openid","session_key":"session_key","unionid":"unionid","errmsg":"errmsg","errcode":0}。
		/// 接口文档：https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
		/// </summary>
		/// <param name="WxCode">通过 wx.login 接口获得临时登录凭证 code</param>
		/// <returns></returns>
		public static string JsCode2Session(string WxCode)
		{
			string strUrl = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
			strUrl = string.Format(strUrl, WxConfig.WxMiniAPPID, WxConfig.WxMiniAPPSECRET, WxCode);
			Log.Debug("微信小程序登录凭证校验(jscode2session)", "请求地址 : " + strUrl);
			string result = HttpService.Get(strUrl);
			Log.Debug("微信小程序登录凭证校验(jscode2session)", "返回数据 : " + result);
			return result;
		}

		/// <summary>
		/// 校验签名，确定返回的数据是否正确
		/// </summary>
		/// <param name="rawData">不包括敏感信息的原始数据字符串</param>
		/// <param name="signature">签名数据</param>
		/// <param name="session_key">会话密钥</param>
		/// <returns></returns>
		public static bool CheckSign(string rawData,string signature,string session_key)
		{
			if (string.IsNullOrEmpty(rawData))
			{
				Log.Error("微信小程序校验签名", "rawData字段不存在!");
				return false;
			}
			if (string.IsNullOrEmpty(signature))
			{
				Log.Error("微信小程序校验签名", "signature字段不存在!");
				return false;
			}
			if (string.IsNullOrEmpty(session_key))
			{
				Log.Error("微信小程序校验签名", "session_key字段不存在!");
				return false;
			}
			string signatureNew = "";
			using (SHA1CryptoServiceProvider provider = new SHA1CryptoServiceProvider())
			{
				signatureNew = BitConverter.ToString(provider.ComputeHash(Encoding.UTF8.GetBytes(rawData + session_key))).Replace("-", string.Empty).ToLower(CultureInfo.CurrentCulture);
			}
			if (signatureNew== signature)
			{
				return true;
			}
			Log.Error("微信小程序校验签名", "签名验证错误！signature：" + signature + "  signatureNew："+ signatureNew);
			return false;
		}

		/// <summary>
		/// 得到解密数据
		/// </summary>
		/// <param name="encryptedData">加密数据</param>
		/// <param name="iv">加密算法的初始向量</param>
		/// <param name="session_key">会话密钥</param>
		/// <returns></returns>
		public static string GetDecryptData(string encryptedData, string iv, string session_key)
		{
			string data = WxUtility.AESDecrypt(session_key, iv, encryptedData);
			if(string.IsNullOrEmpty(data))
			{
				Log.Error("微信小程序得到解密数据失败", "原始加密数据（encryptedData）：" + encryptedData + " iv：" + iv + " session_key：" + session_key);
			}
			return data;
		}

		/// <summary>
		/// 获取小程序码，适用于需要的码数量极多的业务场景。通过该接口生成的小程序码，永久有效，数量暂无限制。
		/// 成功返回二维码路径(例：D:\MyProject\a.png)，失败返回json：{"errmsg":"errmsg","errcode":0}
		/// </summary>
		/// <param name="qrCodePath">二维码路径(例：D:\MyProject\a.png)</param>
		/// <param name="access_token">接口调用凭证</param>
		/// <param name="scene">页面路径中带的参数（例：pid=xxx）</param>
		/// <param name="page">二维码要跳转到的页面路径(例：pages/login/login)</param>
		/// <param name="width">二维码的宽度，单位 px</param>
		/// <param name="auto_color">自动配置线条颜色</param>
		/// <param name="line_color">auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"} 十进制表示</param>
		/// <param name="is_hyaline">是否需要透明底色</param>
		/// <returns></returns>
		public static string GetQRCodeByUnlimited(string qrCodePath,string access_token, string scene, string page,int width=430,bool auto_color=true,string line_color="",bool is_hyaline=false)
		{
			if (string.IsNullOrEmpty(qrCodePath))
			{
				Log.Error("微信小程序生成二维码", "qrCodePath字段不存在!");
				return "";
			}
			if (string.IsNullOrEmpty(access_token))
			{
				Log.Error("微信小程序生成二维码", "access_token字段不存在!");
				return "";
			}
			if (string.IsNullOrEmpty(scene))
			{
				Log.Error("微信小程序生成二维码", "scene字段不存在!");
				return "";
			}
			if (string.IsNullOrEmpty(page))
			{
				Log.Error("微信小程序生成二维码", "page字段不存在!");
				return "";
			}
			if (string.IsNullOrEmpty(line_color))
			{
				line_color = "{\"r\":\"0\",\"g\":\"0\",\"b\":\"0\"}";
			}
			string strImageDir = Path.GetDirectoryName(qrCodePath) + "\\";
			string strImageName = Path.GetFileName(qrCodePath);
			if (!Directory.Exists(strImageDir))
			{
				Directory.CreateDirectory(strImageDir);
			}

			string strUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}";
			strUrl = string.Format(strUrl, access_token);
			var tempEntity = new { scene = scene, page = page, width=width, auto_color = auto_color, is_hyaline= is_hyaline };
			string param = JsonMapper.ToJson(tempEntity);
			Log.Debug("微信小程序生成二维码", "请求地址：" + strUrl + " 参数：" + param);
			var result = HttpService.HttpPostResultByte(strUrl, param, "application/json");
			string strResult = Encoding.UTF8.GetString(result);
			if (strResult.Contains("errmsg"))
			{
				Log.Error("微信小程序生成二维码", "返回数据：" + strResult);
				return strResult;
			}
			File.WriteAllBytes(qrCodePath, result);
			Log.Debug("微信小程序生成二维码", "生成成功：" + qrCodePath);
			return qrCodePath;
		}
	}
}
